package tgc.edu.tms.web.controller;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaBuilder.In;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.tomcat.jni.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import tgc.edu.tms.custom.AjaxResult;
import tgc.edu.tms.custom.CommonController;
import tgc.edu.tms.custom.ImportExcel;
import tgc.edu.tms.entity.ClassSchedule;
import tgc.edu.tms.entity.Profession;
import tgc.edu.tms.entity.Student;
import tgc.edu.tms.entity.SysRole;
import tgc.edu.tms.entity.SysUser;
import tgc.edu.tms.entity.TbClass;
import tgc.edu.tms.security.UserUtils;
import tgc.edu.tms.service.ClassScheduleService;
import tgc.edu.tms.service.ProfessionService;
import tgc.edu.tms.service.SchoolyearService;
import tgc.edu.tms.service.StudentService;
import tgc.edu.tms.service.SysRoleService;
import tgc.edu.tms.service.SysUserService;
import tgc.edu.tms.service.TbClassService;
import tgc.edu.tms.web.form.StudentForm;

@Controller
@RequestMapping(value = "/student")
public class StudentController extends CommonController<Student, Integer, StudentForm> {
	@Autowired
	private StudentService service;
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private TbClassService tbClassService;
	@Autowired
	private ProfessionService profesionService;
	@Autowired
	private StudentService studentService;
	@Autowired
	private SchoolyearService schoolyearService;
	@Autowired
	private UserUtils userTtils;
	@Autowired
	private ClassScheduleService classScheduleService;

	@RequestMapping(value = "/edits")
	public Object edits(StudentForm form, ModelMap map) throws InstantiationException, IllegalAccessException {
		/*
		 * if(form.getYear()==null||form.getYear()==""&&form.getProfesion()==null||form.
		 * getProfesion()==""&&form.getTbclass()==null||form.getTbclass()=="") {
		 * if(form.getId()==null) { return "student/studenterror"; } }
		 */
		Student model = new Student();
		model = null;
		Integer id = form.getId();
		if (id != null) {
			model = service.findById(id);
		}
		map.put("model", model);
		return "student/edit";
	}

	@Override
	public Object save(StudentForm form) {
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		try {
			String username = form.getUsername();
			SysUser sysUser = sysUserService.findByUsername(username);
			Student model = new Student();
			Integer id = form.getId();
			if (id != null) {
				model = service.findById(id);
			}
			if (id == null && sysUser != null) {
				return new AjaxResult(false, "学号已存在！");
			}
			if (form.getTbclass() == null) {
				return new AjaxResult(false, "班级不能为空！");
			}
			if (form.getSex() == null) {
				return new AjaxResult(false, "性别不能为空！");
			}
			String profesion = form.getProfesion();
			if (profesion != null && form.getTbclass() != null) {
				Profession findByyearAndprofesion = profesionService.findByyearAndprofesion(form.getYear(), profesion);
				TbClass findByProfessionIDAndtbclassName = tbClassService
						.findByProfessionIDAndtbclassName(findByyearAndprofesion.getId(), form.getTbclass());
				System.out.println(findByProfessionIDAndtbclassName.getId());
				System.out.println(findByProfessionIDAndtbclassName.getName());
				model.setTbClass(findByProfessionIDAndtbclassName);
			}

			String password = form.getPassword();
			if (StringUtils.hasText(password)) {
				password = encoder.encode(password);
				model.setPassword(password);
			}
			if (!StringUtils.hasText(model.getPassword())) {
				model.setPassword(encoder.encode("123456"));
			}
			BeanUtils.copyProperties(form, model, "id", "password", "year", "profesion", "tbClass");

			List<SysRole> roles = model.getRoles();
			if (roles.isEmpty()) {
				String code = "ROLE_STUDENT";
				model.getRoles().add(sysRoleService.findbyCode(code));
			}
			service.save(model);
			Profession findByyearAndprofesion = profesionService.findByyearAndprofesion(form.getYear(), profesion);
			TbClass findByProfessionIDAndtbclassName = tbClassService
					.findByProfessionIDAndtbclassName(findByyearAndprofesion.getId(), form.getTbclass());
			Integer findtiaoshu = tbClassService.findtiaoshu(findByProfessionIDAndtbclassName.getId());
			findByProfessionIDAndtbclassName.setNumber(findtiaoshu);
			tbClassService.save(findByProfessionIDAndtbclassName);
			return new AjaxResult("OK");
		} catch (Exception e) {
			return new AjaxResult(false, "数据保存失败");
		}
	}

	@Override
	public Object delete(Integer id) {
		try {
			Student findById = studentService.findById(id);
			TbClass findById2 = tbClassService.findById(findById.getTbClass().getId());
			if (findById2.getNumber() > 0) {
				findById2.setNumber(findById2.getNumber() - 1);
			}
			tbClassService.save(findById2);
			studentService.deleteById(id);
			return new AjaxResult("OK");
		} catch (Exception e) {
			return new AjaxResult(false, "数据保存失败");
		}
	}

	@Override
	public Specification<Student> buildSpec(StudentForm form) {
		Specification<Student> spec = new Specification<Student>() {

			@Override
			public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if (StringUtils.hasText(form.getYear())) {
					rules.add(cb.like(root.get("tbClass").get("profession").get("year"), "%" + form.getYear() + "%"));
				}
				if (StringUtils.hasText(form.getProfesion())) {
					rules.add(cb.like(root.get("tbClass").get("profession").get("profesion"),
							"%" + form.getProfesion() + "%"));
				}
				if (StringUtils.hasText(form.getTbclass())) {
					rules.add(cb.like(root.get("tbClass").get("name"), "%" + form.getTbclass() + "%"));
				}
				if (StringUtils.hasText(form.getSearch())) {
					Predicate phone = cb.like(root.get("phone"), "%" + form.getSearch() + "%");
					Predicate email = cb.like(root.get("email"), "%" + form.getSearch() + "%");
					Predicate sex = cb.like(root.get("sex"), "%" + form.getSearch() + "%");
					Predicate age = cb.like(root.get("age"), "%" + form.getSearch() + "%");
					Predicate addrs = cb.like(root.get("addrs"), "%" + form.getSearch() + "%");
					Predicate tbclass = cb.like(root.get("tbClass").get("name"), "%" + form.getSearch() + "%");
					Predicate or = cb.or(phone, email, sex, age, addrs, tbclass);
					rules.add(or);
				}

				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}

		};
		return spec;
	}

	// 查找所有的年级
	@RequestMapping(value = "/year")
	@ResponseBody
	public Object year() {
		List<String> findAllyear = profesionService.findAllYear();
		return findAllyear;
	}

	// 根据年级查找所有专业
	@RequestMapping(value = "/profesion")
	@ResponseBody
	public Object profesion(String year) {
		return profesionService.findProfesionByYear(year);
	}

	// 根据年级和专业查找所有班级
	@RequestMapping(value = "/tbClass")
	@ResponseBody
	public Object tbClass(String year, String profesion) {
		Integer professionid = profesionService.findIdByProfesionAndYear(profesion, year);
		List<TbClass> findById = tbClassService.findByprofessionID(professionid);
		return findById;
	}

	// 查询时加载所有年级
	@RequestMapping(value = "/years")
	@ResponseBody
	public Object years() {
		List<String> findAll = profesionService.findAllYear();
		return findAll;
	}
	
	// 根据年级查询所有学院
	@RequestMapping(value = "/college")
	@ResponseBody
	public Object collect(String year) {// 查询选择的参数
		return profesionService.findCollegeByYear(year);
	}
	
	// 根据年级查询所有专业
	@RequestMapping(value = "/profesions")
	@ResponseBody
	public Object profesions(String year,String college) {// 查询选择的参数
		return profesionService.findByCollegeAndYear(college, year);
	}

	// 根据年级和专业查找所有班级
	@RequestMapping(value = "/banji")
	@ResponseBody
	public Object banji(String year, String profesion) {
		Integer professionid = profesionService.findIdByProfesionAndYear(profesion, year);
		return tbClassService.findByprofessionID(professionid);
	}

	/**
	 * 导入学生信息excel
	 * 
	 * @param file excel文件名
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/excelimport")
	@ResponseBody
	public Object excelimport(MultipartFile file) throws IOException {
		try {
			// 实例化工具类
			ImportExcel excelReader = new ImportExcel();
			InputStream is = file.getInputStream();
			// 导入excel
			excelReader.readExcelContent(is);
			Map<Integer, String> map = excelReader.readExcelContent(is);
			is.close();
			// 这里由于xls合并了单元格需要对索引特殊处理
			for (int i = 3; i <= map.size() + 1; i++) {
				String[] scoreArray = map.get(i).split("-");
				System.out.println(map.get(i));
				String year = scoreArray[1];
				List<Profession> years = profesionService.findYear(year);
				System.out.println(years);
				if (years == null) {
					return "第" + (i + 1) + "年级数据未找到,请检查!";
				}
				String profesion = scoreArray[2];
				Profession findAll = profesionService.findByyearAndprofesion(years.get(0).getYear(), profesion);
				if (findAll == null) {
					return "第" + (i + 1) + "专业数据未找到,请检查!";
				}
				String tbclassname = scoreArray[3];
				TbClass findtbAll = tbClassService.findByProfessionIDAndtbclassName(findAll.getId(), tbclassname);
				if (findtbAll == null) {
					return "第" + (i + 1) + "班级数据未找到,请检查!";
				}
				String username = scoreArray[4];
				SysUser findByUsername = sysUserService.findByUsername(username);
				if (findByUsername != null) {
					return "第" + (i + 1) + "学号数据已存在,请检查!";
				}
				String name = scoreArray[5];
				/*
				 * String sex=scoreArray[6]; String nan="男"; String nv="女"; if(sex!=null) {
				 * if(sex==nan||sex==nv) { return "第"+(i+1)+"性别数据填写有误,请检查!"; } }
				 */
				/*
				 * String number=scoreArray[7]; Student numberall=
				 * studentService.findByPhone(number); if(numberall!=null) { return
				 * "第"+(i+1)+"手机号数据已存在,请检查!"; }
				 */
				/*
				 * String email=scoreArray[8]; if
				 * (!email.matches("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+")) { return
				 * "邮箱格式错误，请检查！"; }
				 */
				/*
				 * String addrs=scoreArray[9]; String job=scoreArray[10]; String jobs="学生";
				 * if(job!=null) { if(!job.equals(jobs)) { return "第"+(i+1)+"职务数据输入有误,请检查!"; } }
				 */
				Student model = new Student();
				model.setUsername(username);
				BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
				model.setPassword(encoder.encode("123456"));
				model.setName(name);
				/*
				 * model.setSex(sex); model.setPhone(number); model.setEmail(email);
				 * model.setAddrs(addrs); model.setJob(job);
				 */
				model.setTbClass(findtbAll);
				List<SysRole> roles = model.getRoles();
				if (roles.isEmpty()) {
					String code = "ROLE_STUDENT";
					model.getRoles().add(sysRoleService.findbyCode(code));
					studentService.save(model);
				}
				Integer findgeshu = studentService.findgeshu(findtbAll.getId());
				findtbAll.setNumber(findgeshu);
				tbClassService.save(findtbAll);
			}
			return "数据保存成功";
		} catch (Exception e) {
			return "数据保存失败";
		}
	}

	/***
	 * 学生跳转查询页面
	 * @return
	 */
	@RequestMapping(value= "/kccx")
	public String kccx(ModelMap map) {
		Student user = service.findByUsername(userTtils.getUser().getUsername());
		String year = user.getTbClass().getProfession().getYear();
		Integer classId = user.getTbClass().getId();
		String className = user.getTbclass();
		String profesion = user.getTbClass().getProfesion();
		map.put("classId", classId);
		map.put("className", className);
		map.put("year", year);
		map.put("profesion", profesion);
		return "main/kccx";
	}
	
	
	@RequestMapping(value= "/getKb")
	@ResponseBody
	public Object getKb(String schoolYear) {
		try {
			Student user = service.findByUsername(userTtils.getUser().getUsername());
			String className = user.getTbclass();//班级
			String profesion = user.getTbClass().getProfesion();//专业
			String year = user.getTbClass().getProfession().getYear();
			Specification<ClassSchedule> spec = new Specification<ClassSchedule>() {
				@Override
				public Predicate toPredicate(Root<ClassSchedule> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
					HashSet<Predicate> rules = new HashSet<>();
					if (StringUtils.hasText(className)) {
						rules.add(cb.like(root.get("searcherclass"), "%"+className+"%"));
					}
					if (StringUtils.hasText(profesion)) {
						rules.add(cb.equal(root.get("ep").get("curriculum").get("profession").get("profesion"), profesion));
					}
					if (StringUtils.hasText(year)) {
						rules.add(cb.equal(root.get("ep").get("curriculum").get("profession").get("year"), year));
					}
					if (StringUtils.hasText(schoolYear)) {
						rules.add(cb.equal(root.get("ep").get("schoolyear").get("xnxq"), schoolYear));
					}
					
/*					In<Object> in = cb.in(root.get("jcb").get("xq"));
					in.value("星期一");					
					in.value("星期二");	
					in.value("星期三");	
					in.value("星期四");	
					in.value("星期五");	*/
					return cb.and(rules.toArray(new Predicate[rules.size()]));
				}
			};
			List<ClassSchedule> all = classScheduleService.findAll(spec);
			return all;
		} catch (Exception e) {
			return "error";
		}
	}

}
